package utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * This class controls the flow of debugging messages (System.out).
 */
public class DebugHandler {

    /**
     * is System.out supposed to be redirected to a file?
     */
    private static boolean isIO = false;
    /**
     * output to a file
     */
    private static PrintStream outstream;
    private static PrintStream outerr;
    /**
     * the default stream (console)
     */
    private static PrintStream sysoDefault = System.out;
    private static PrintStream syserrDefault = System.err;
    /**
     * path to the debug log used if isIO is true
     */
    private static File fileOut = new File("sysout.log");
    private static File fileErr = new File("syserr.log");

    /**
     * Enable or disable debug messages altogether.
     * If disabled, System.out will not print anything
     * @param b true to enable, false to disable
     */
    public static void setEnabled(boolean b){
        if(b == false){
            System.setOut(new PrintStream(new OutputStream(){
                @Override
                public void write(int i){
                    //Do nothing
                }
            }));
            System.setErr(new PrintStream(new OutputStream(){
                @Override
                public void write(int i){
                    //Do nothing
                }
            }));

        }
        else{
            if(isIO){
                routeStreams();
            }else{
                resetStreamDefaults();
            }
        }
    }

    private static void resetStreamDefaults(){
        System.setOut(sysoDefault);
        System.setErr(syserrDefault);
    }

    private static void routeStreams(){
        System.setOut(outstream);
        System.setErr(outerr);
    }

    /**
     * Reroutes System.out to a file, or resets it back to the console.
     * @param b true to reroute, false to reset.
     */
    public static void setIO(boolean b){
        if(b == false && isIO == true){
            resetStreamDefaults();
            isIO = false;
            return;
        }

        try {
            outstream = new PrintStream(new FileOutputStream(fileOut)){
                @Override
                public void println(String x){
                    Calendar cal = Calendar.getInstance();
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SSS");
                    x = sdf.format(cal.getTime())+": "+x;
                    super.println(x);
                };

                @Override
                public void println(boolean x){
                    println(""+x);
                };

                @Override
                public void println(Object x){
                    println(x.toString());
                };

                @Override
                public void println(char x){
                    println(""+x);
                };
            };
            Calendar cal = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ" );
            outstream.write("Debug Log\n".getBytes());
            outstream.write((sdf.format(cal.getTime())+"\n").getBytes());
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            outerr = new PrintStream(new FileOutputStream(fileErr)){
                @Override
                public void println(String x){
                    Calendar cal = Calendar.getInstance();
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SSS");
                    x = sdf.format(cal.getTime())+": "+x;
                    super.println(x);
                };

                @Override
                public void println(boolean x){
                    println(""+x);
                };

                @Override
                public void println(Object x){
                    println(x.toString());
                };

                @Override
                public void println(char x){
                    println(""+x);
                };
            };
            Calendar cal = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ" );
            outerr.write("Error Log\n".getBytes());
            outerr.write((sdf.format(cal.getTime())+"\n").getBytes());
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        routeStreams();
        isIO = b;
    }
}
